package com.mercenary.wein.screenControl.command;

import com.android.ddmlib.NullOutputReceiver;
import com.mercenary.wein.screenControl.bean.CommandBean;
import com.mercenary.wein.screenControl.command.jobSchedual.QuartzManager;
import com.mercenary.wein.screenControl.command.jobSchedual.TaskJob;
import com.mercenary.wein.screenControl.command.jobSchedual.TestJob;
import com.mercenary.wein.screenControl.service.CommandService;
import com.mercenary.wein.screenControl.ui.MainFrame;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.SchedulerException;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.*;

/**
 * Created by tuxiao on 2017/3/12.
 */
public class CommandPool {

    static Log log = LogFactory.getLog(CommandPool.class);
    private static BlockingQueue<Map<String, String>> resultQueue = new ArrayBlockingQueue<Map<String, String>>(500);

    private static ExecutorService pool = Executors.newFixedThreadPool(70);//最多70台机器
    private static ExecutorService exeHandler = Executors.newFixedThreadPool(10); //可以10组并行
    private static ExecutorService resultHandler = Executors.newSingleThreadExecutor();
    private static CommandService commandService = new CommandService();

    public static void sendCommand(final List<CommandBean> command) {
        StringBuilder deviceList = new StringBuilder("[ ");
        for (final CommandBean c : command) {
            try {
                QuartzManager.exeJob(new TaskJob(),c);
//                QuartzManager.test(new TestJob());
            } catch (SchedulerException e) {
                log.info("===============================执行器调度失败！=========================");
                e.printStackTrace();
            } catch (ParseException e) {
                log.info("===============================时间参数解析失败！=========================");
                e.printStackTrace();
            }
        }
    }

    protected static void sendCommand_(final List<CommandBean> command) {
        exeHandler.execute(new Runnable() {
            public void run() {
                StringBuilder deviceList = new StringBuilder("[ ");
                Map<String, String> results = new HashMap<String, String>();
                List<Callable<String>> tasks = new ArrayList<Callable<String>>();
                for (final CommandBean device : command) {
                    deviceList.append(device.getSerialNo() + " ");
                    tasks.add(new Callable() {
                        public String call() {
                            while (true) {
                                long[] result = commandService.isRunning(device.getSerialNo());
                                if (result[0] == 0) {//没有正在执行的任务
                                    break;
                                } else if (new Date().getTime() - result[1] > 1000 * 60 * 2) {//有正在执行的任务则将该任务状态改成失败
                                    commandService.shutdownTask(result[0]);
                                    break;
                                }
                                try {
                                    Thread.sleep(5000l);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            final long id = commandService.insertTask(device);
                            String result = null;
                            try {
                                CommandSocketClient csc = new CommandSocketClient("127.0.0.1", device.getPort());
                                String res = csc.command(device.getContent());
                                if (res.equals("2003")) {
                                    commandService.updateTask(id, 1);
                                } else if (res.equals("2001")) {
                                    commandService.shutdownTask(id);
                                    MainFrame.dcdMap.get(device.getSerialNo()).getAndroidDevice().executeShellCommand("", new NullOutputReceiver());
                                }
                                result = id + "|" + device.getSerialNo() + "|" + res;
                                csc.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                                commandService.shutdownTask(id);
                            }
                            return result;
                        }
                    });
                }
                log.info("send command to devices:" + deviceList.append(" ]") + " command:" + command);
                try {
                    List<Future<String>> res = pool.invokeAll(tasks, 10, TimeUnit.MINUTES);
                    for (Future<String> r : res) {
                        String back = "";
                        try {
                            back = r.get();
                            String[] t = back.split("\\|");
                            results.put(t[1], t[2]);
                            log.info("answer from app:" + t[1] + "->" + t[2]);
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.info("command receive error:" + back);
                        }
                    }
                } catch (InterruptedException e) {
                    log.info("tasks submit error!");
                    e.printStackTrace();
                }
                resultQueue.add(results);
            }
        });
        resultHandler.execute(new Runnable() {
                                  public void run() {
                                      while (true) {
                                          try {
                                              Map<String, String> result = resultQueue.take();
                                              for (Map.Entry<String, String> entry : result.entrySet()) {
                                                  log.info("haahah" + entry.getKey() + " " + entry.getValue());
                                              }
                                          } catch (InterruptedException e) {
                                              e.printStackTrace();
                                          }
                                      }
                                  }
                              }
        );
    }

}
